import csv
import os
import time
from typing import List

import toml
from PySide6 import QtCore
from PySide6.QtCore import QAbstractTableModel, Qt, QThread, QRunnable, QObject, Signal, Slot, QThreadPool
from PySide6.QtGui import QStandardItemModel, QStandardItem
from PySide6.QtWidgets import QApplication, QMessageBox, QMainWindow, QTableWidgetItem, QHeaderView
from PySide6.QtUiTools import QUiLoader
from ui_main import Ui_mainWindow
import subprocess
import requests

with open("./config.toml", "r", encoding="utf-8") as f:
    config = toml.load(f)
    print(config)


class WorkerSignals(QObject):
    update_data = Signal(int, int, str)


class DataWorker(QRunnable):

    def __init__(self, args, format_str, py_code):
        super().__init__()
        self.signals = WorkerSignals()
        self.args = args
        self.format_str = format_str
        self.py_code = py_code

    def run(self):
        for row_index, arg in enumerate(self.args.strip().split()):
            self.signals.update_data.emit(row_index, 0, arg)
            cmd = self.format_str.format(arg)
            print(cmd)
            process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True)
            out = ""
            for i in range(10):
                stdout = process.stdout.readline()
                if not stdout:
                    break
                out += stdout
                self.signals.update_data.emit(row_index, 1, out)
            process.kill()
            if self.py_code:
                handle_response = self.init_py_code()
                res: List[str] = handle_response(out)
                self.signals.update_data.emit(row_index, 2, "\n".join(res))

    def init_py_code(self):
        namespace = {}
        exec(self.py_code, namespace)
        return namespace['handle_response']


class MainWindow(QMainWindow, Ui_mainWindow):

    def __init__(self):
        # 从文件中加载UI定义
        super(MainWindow, self).__init__()
        self.setupUi(self)
        self.name.addItems(config.keys())
        self.name.currentIndexChanged.connect(self.item_change)
        self.run.clicked.connect(self.handle)
        self.saveCMD.clicked.connect(self.save_code)
        self.saveLocal.clicked.connect(self.save_to_csv)
        self.init_table_view()
        # 线程池
        self.thread_pool = QThreadPool()
        self.worker = None

    def save_to_csv(self):
        dirs = self.name.currentText()
        os.makedirs(dirs, exist_ok=True)
        filename = f"./{dirs}/result{time.time()}.csv"
        with open(filename, 'w', newline='', encoding="utf-8-sig") as file:
            writer = csv.writer(file)
            # 写入表头
            # 正确获取水平表头标签
            header_labels = []
            for col in range(self.tableModel.columnCount()):
                header_labels.append(
                    self.tableModel.headerData(col, QtCore.Qt.Horizontal)
                )
            writer.writerow(header_labels)  # 写入表头
            # 遍历模型中的所有行并写入数据
            for row_index in range(self.tableModel.rowCount()):
                row_data = []
                for column_index in range(self.tableModel.columnCount()):
                    item = self.tableModel.item(row_index, column_index)
                    if item:
                        row_data.append(item.text())
                writer.writerow(row_data)
        print(f"Data exported to {filename}")

    def save_code(self):
        global config
        name = self.name.currentText()
        format_str = self.formatLine.text()
        py_code = self.pythonCode.toPlainText()
        if name in config:
            return
        config[name] = {"cmd": format_str, "py_code": py_code}
        with open("./config.toml", "w", encoding="utf-8") as f:
            toml.dump(config, f)
        print("saved config")
        # 重新获取配置
        with open("./config.toml", "r", encoding="utf-8") as f:
            config = toml.load(f)
        self.name.clear()
        self.name.addItems(config.keys())
        self.name.setCurrentText(name)

    def item_change(self):
        item_name = self.name.currentText()
        if item_name:
            format_str = config[item_name]["cmd"]
            self.formatLine.setText(format_str)
            py_code = config[item_name]["py_code"]
            self.pythonCode.setText(py_code)

    def init_table_view(self):
        self.tableModel = QStandardItemModel(1, 3)
        self.tableModel.setHorizontalHeaderLabels(['参数', '结果', '格式结果'])
        self.resTableView.setModel(self.tableModel)
        # 启用表格视图的自动换行
        self.resTableView.setWordWrap(True)
        # 自动调整行高以适应内容
        self.resTableView.resizeRowsToContents()
        # 自动调整列宽
        self.resTableView.horizontalHeader().setSectionResizeMode(0, QHeaderView.ResizeToContents)  # 第1列根据内容调整
        self.resTableView.horizontalHeader().setSectionResizeMode(1, QHeaderView.Stretch)  # 第2列填充剩余空间
        self.resTableView.horizontalHeader().setSectionResizeMode(2, QHeaderView.ResizeToContents)  # 第3列根据内容调整

    def handle(self):
        # 读取名称、格式化命令、python格式化脚本
        name = self.name.currentText()
        format_str = self.formatLine.text()
        py_code = self.pythonCode.toPlainText()
        args = self.argsInput.toPlainText()

        print(name, format_str, args, py_code)
        self.tableModel.clear()
        self.init_table_view()
        self.resTableView.viewport().update()
        # 预处理输入
        self.worker = DataWorker(args, format_str, py_code)
        self.worker.signals.update_data.connect(self.update_model)
        self.thread_pool.start(self.worker)

    def update_model(self, row_index, col_index, value):
        """更新模型数据 - 主线程安全"""
        item = QStandardItem(value)
        item.setTextAlignment(Qt.AlignLeft | Qt.AlignVCenter | Qt.TextWordWrap)
        self.tableModel.setItem(row_index, col_index, item)

        # 刷新表格视图
        self.resTableView.resizeRowsToContents()
        self.resTableView.viewport().update()


if __name__ == '__main__':
    app = QApplication()
    stats = MainWindow()
    stats.show()
    app.exec()
